module mculib.arm.itm;
/**
* 远程跟踪调试
*/

version(None):

import mculib.chip;

enum bool SupportITM = imported!"mculib.baremetal".CheckTargetCPU!("cortex-m3","cortex-m4","cortex-m7");

static assert(SupportITM,"ITM is not supported in this CPU");

final abstract class DITM
{

}

uint write(uint data)
{
    return 0;
}


	struct DBG_Type {
		enum AddressBlock[]  Block = [];
		enum Interrupt[]  IRQs = [];

		@RegInfo("DBGMCU_IDCODE",0x0) RegVolatile!(mask_DBGMCU_IDCODE,uint,0xe0042000,0x10006411,RegisterAccess.RO) DBGMCU_IDCODE;		 // offset:0x0 DBGMCU_IDCODE IDCODE
		@RegInfo("DBGMCU_CR",0x4) RegVolatile!(mask_DBGMCU_CR,uint,0xe0042004,0x0,RegisterAccess.RW) DBGMCU_CR;		 // offset:0x4 DBGMCU_CR Control Register
		@RegInfo("DBGMCU_APB1_FZ",0x8) RegVolatile!(mask_DBGMCU_APB1_FZ,uint,0xe0042008,0x0,RegisterAccess.RW) DBGMCU_APB1_FZ;		 // offset:0x8 DBGMCU_APB1_FZ Debug MCU APB1 Freeze registe
		@RegInfo("DBGMCU_APB2_FZ",0xc) RegVolatile!(mask_DBGMCU_APB2_FZ,uint,0xe004200c,0x0,RegisterAccess.RW) DBGMCU_APB2_FZ;		 // offset:0x12 DBGMCU_APB2_FZ Debug MCU APB2 Freeze registe
		enum mask_DBGMCU_IDCODE {
				DEV_ID = RegBitField!uint(0,12,RegisterAccess.RO),		// DEV_ID
				REV_ID = RegBitField!uint(16,16,RegisterAccess.RO),		// REV_ID
		}
		enum mask_DBGMCU_CR {
				DBG_SLEEP = RegBitField!uint(0,1,RegisterAccess.RW),		// DBG_SLEEP
				DBG_STOP = RegBitField!uint(1,1,RegisterAccess.RW),		// DBG_STOP
				DBG_STANDBY = RegBitField!uint(2,1,RegisterAccess.RW),		// DBG_STANDBY
				TRACE_IOEN = RegBitField!uint(5,1,RegisterAccess.RW),		// TRACE_IOEN
				TRACE_MODE = RegBitField!uint(6,2,RegisterAccess.RW),		// TRACE_MODE
		}
		enum mask_DBGMCU_APB1_FZ {
				DBG_TIM2_STOP = RegBitField!uint(0,1,RegisterAccess.RW),		// DBG_TIM2_STOP
				DBG_TIM3_STOP = RegBitField!uint(1,1,RegisterAccess.RW),		// DBG_TIM3 _STOP
				DBG_TIM4_STOP = RegBitField!uint(2,1,RegisterAccess.RW),		// DBG_TIM4_STOP
				DBG_TIM5_STOP = RegBitField!uint(3,1,RegisterAccess.RW),		// DBG_TIM5_STOP
				DBG_WWDG_STOP = RegBitField!uint(11,1,RegisterAccess.RW),		// DBG_WWDG_STOP
				DBG_IWDEG_STOP = RegBitField!uint(12,1,RegisterAccess.RW),		// DBG_IWDEG_STOP
				DBG_I2C1_SMBUS_TIMEOUT = RegBitField!uint(21,1,RegisterAccess.RW),		// DBG_J2C1_SMBUS_TIMEOUT
				DBG_I2C2_SMBUS_TIMEOUT = RegBitField!uint(22,1,RegisterAccess.RW),		// DBG_J2C2_SMBUS_TIMEOUT
				DBG_I2C3SMBUS_TIMEOUT = RegBitField!uint(23,1,RegisterAccess.RW),		// DBG_J2C3SMBUS_TIMEOUT
		}
		enum mask_DBGMCU_APB2_FZ {
				DBG_TIM1_STOP = RegBitField!uint(0,1,RegisterAccess.RW),		// TIM1 counter stopped when core is halted
				DBG_TIM9_STOP = RegBitField!uint(16,1,RegisterAccess.RW),		// TIM9 counter stopped when core is halted
				DBG_TIM10_STOP = RegBitField!uint(17,1,RegisterAccess.RW),		// TIM10 counter stopped when core is halted
				DBG_TIM11_STOP = RegBitField!uint(18,1,RegisterAccess.RW),		// TIM11 counter stopped when core is halted
		}
	}
	




version(None):
import arm;
//import arm.misc;


/*
private enum bool hasBusPeriph = CheckTargetCPU!("cortex-m3","cortex-m4","cortex-m7","cortex-m23","cortex-m33");

static if(hasBusPeriph):
*/
import arm.bus;


static interface ITM  //: MMIOBus!(MMIO!(CorePeripheralAddress.ITM_Base,ITM_Type))
{
    private enum ITM_Type* mBase = MMIO!(CorePeripheralAddress.ITM_Base,ITM_Type);

    /// 默认写入0
    enum flagPrivMask
    {
        AccessPort0 = 1 << 0,   /// 0...7 的端口访问权限 1:特权级别 0:非特权级别
        AccessPort1 = 1 << 1,   /// 8...15 的端口访问权限 1:特权级别 0:非特权级别
        AccessPort2 = 1 << 2,   /// 16...23 的端口访问权限 1:特权级别 0:非特权级别
        AccessPort3 = 1 << 3,   /// 24...31 的端口访问权限 1:特权级别 0:非特权级别
    }

    static uint putChar(ubyte)
    {
        return 0;
    }

    /+
    __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
    {
    if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
        ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
    {
        while (ITM->PORT[0U].u32 == 0UL)
        {
        __NOP();
        }
        ITM->PORT[0U].u8 = (uint8_t)ch;
    }
    return (ch);
    }
    +/
}

struct ITM_Type
{
    struct Register{
        string v1;
        uint v2;
    }
    enum mask_TPR
    {
        PRIVMASK = 0x0F,
    }
    /// Trace 控制寄存器
    enum mask_TCR
    {
        ITMENA = 1 << 0,    /// ITM 使能 , 必须在使用前 置位
        TSENA = 1 << 1,     /// 时间戳使能
        SYNCENA = 1 << 2,   /// 同步使能 相关 CPU_DWT:CTRL.SYNCTAP
        DWTENA = 1 << 3,    /// DWT 使能
        SWOENA = 1 << 4,    /// 异步时间戳使能(TSENA=1)
        TSPRESCALE = 0x3 << 8,  /// 时间戳预分频 0:1 1:4 2:16 3:64
        GTSFREQ = 0x3 << 10,    /// 全局时间戳频率 0:4M 1:2M 2:1M 3:500K
        ATBID = 0x7F << 16,    /// 跟踪总线 ID
        BUSY = 1 << 23,     /// 忙标志
    }

    enum mask_LAR
    {
        LOCK_ACCESS = uint.max,
    }

    enum mask_LSR
    {
        PRESENT = 1 << 0,   /// 当前状态 0:锁定 1:未锁定
        ACCESS = 1 << 1,    /// 阻止写入 1:阻止
        BYTEACC = 1 << 2,   /// byte 访问锁定
    }
    
    enum mask_IWR
    {
        ATVALIDM = 1 << 0,  /// 集成写入寄存器有效
    }
    enum mask_IRR
    {
        ATREADYM = 1 << 0,  /// 集成读取寄存器有效
    }

    enum mask_IMCR
    {
        INTEGRATION = 1 << 0,   /// 集成模式 0:非集成模式 1:集成模式
    }
    @disable this();
    union _PORT
    {
        ubyte u8;
        ushort u16;
        uint u32;
    };
    /// 对齐
    align(1):
    /// ITM 端口寄存器, 数据为 FIFO 反馈在 TER 寄存器的对应位上
    @Register("read-write",0x00)    _PORT[32]   PORT;
    /// 保留
    uint[864]   RESERVED0;
    /// ITM 反馈对应寄存器写满 0:满 1:未满
    @Register("read-write",0x0e00)   uint   TER;
    /// 保留
    uint[15]   RESERVED1;
    /// ITM跟踪特权寄存器 [3:0] 1:为特权级别 0:为非特权级别
    @Register("read-write",0x0e40)   uint   TPR;
    /// 保留
    uint[15]   RESERVED2;
    /// ITM跟踪控制寄存器
    @Register("read-write",0x0e80)   uint   TCR;
    /// 保留
    uint[29]   RESERVED3;
    /// ITM集成写入寄存器
    @Register("write-only",0x0eF8)  uint   IWR;
    /// ITM集成读取寄存器
    @Register("read-only",0x0eFC)  uint   IRR;
    /// ITM集成控制寄存器
    @Register("read-write",0x0F00)  uint   IMCR;
    /// 保留
    uint[43]   RESERVED4;
    /// ITM Lock Access Register , 控制 TER, TPR 和 TCR. 寄存器写入权限 写入$(D 0xC5ACCE55) 获得权限
    @Register("write-only",0x0FB0)  uint   LAR;
    /// ITM 锁定状态寄存器
    @Register("read-only",0x0FB4)   uint   LSR;
    /// 保留
    uint[6]   RESERVED5;
    /// ITM Peripheral Identification Register #4
    @Register("read-only",0x0FD0)   uint   PID4;
    /// ITM Peripheral Identification Register #5
    @Register("read-only",0x0FD4)   uint   PID5;
    /// ITM Peripheral Identification Register #6
    @Register("read-only",0x0FD8)   uint   PID6;
    /// ITM Peripheral Identification Register #7
    @Register("read-only",0x0FDC)   uint   PID7;
    /// ITM Peripheral Identification Register #0
    @Register("read-only",0x0FE0)   uint   PID0;
    /// ITM Peripheral Identification Register #1
    @Register("read-only",0x0FE4)   uint   PID1;
    /// ITM Peripheral Identification Register #2
    @Register("read-only",0x0FE8)   uint   PID2;
    /// ITM Peripheral Identification Register #3
    @Register("read-only",0x0FEC)   uint   PID3;
    /// ITM Component Identification Register #0
    @Register("read-only",0x0FF0)   uint   CID0;
    /// ITM Component Identification Register #1
    @Register("read-only",0x0FF4)   uint   CID1;
    /// ITM Component Identification Register #2
    @Register("read-only",0x0FF8)   uint   CID2;
    /// ITM Component Identification Register #3
    @Register("read-only",0x0FFC)   uint   CID3;
}


version(NONE):
/**
* 通道设置
*/
enum Channel{
    Clear = 0x00,
    Channel1 = 1 << 0,
    Channel2 = 1 << 1,
    Channel3 = 1 << 2,
    Channel4 = 1 << 3,
}

/// itm
final abstract class ITM{
    /// 外设地址
    enum PeripheralAddress = CorePeripheralAddress.ITM_Base;
    /// ITM 结构体

    /// 寄存器指针
    enum ITM_Struct* pITM = RegMap!(PeripheralAddress,ITM_Struct);



}


